package cn.yshujia.repository;

import cn.yshujia.domain.entity.User;
import cn.yshujia.domain.vo.UserVO;
import cn.yshujia.mapper.UserMapper;
import cn.yshujia.service.impl.RoleServiceImpl;
import cn.yshujia.transform.UserTransform;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Repository;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author YShuJia
 * @create 2025/1/7
 * @description UserRepository
 */


@Repository
public class UserRepository {
	
	@Resource
	private UserMapper userMapper;
	
	@Resource
	private RoleServiceImpl roleService;
	
	@Resource
	private RedisTemplate<String, String> redisToken;
	
	@Resource
	private RedisTemplate<String, UserVO> redisUserVO;
	
	
	private final String VO = "user:";
	
	private final String TOKEN = "token:";
	
	private final Duration DURATION = Duration.ofDays(7L);
	
	@Async ("Task")
	public void setToken(String token, Long id) {
		redisToken.opsForValue().set(TOKEN + id, token);
	}
	
	public String getToken(Long id) {
		return redisToken.opsForValue().get(TOKEN + id);
	}
	
	@Async ("Task")
	public void setUser(UserVO vo) {
		redisUserVO.opsForValue().set(VO + vo.getId(), vo, DURATION);
	}
	
	public UserVO getUser(Long userId) {
		UserVO userVO = redisUserVO.opsForValue().get(VO + userId);
		if (null != userVO) {
			return userVO;
		}
		User user = userMapper.selectById(userId);
		if (null == user) {
			redisUserVO.opsForValue().set(VO + userId, new UserVO());
			return null;
		}
		userVO = UserTransform.entity2VO(user);
		userVO.setRole(roleService.selectById(user.getRoleId()));
		setUser(userVO);
		return userVO;
	}
	
	public List<UserVO> createUserList(List<User> list) {
		List<UserVO> voList = new ArrayList<>();
		for (User user : list) {
			UserVO vo = UserTransform.entity2VO(user);
			vo.setRole(roleService.selectById(user.getRoleId()));
			voList.add(vo);
		}
		return voList;
	}
	
	@Async ("Task")
	public void del() {
		Set<String> keys = redisToken.keys(VO + "*");
		redisToken.delete(keys);
	}
	
	@Async ("Task")
	public void delToken(Long id) {
		redisToken.delete(TOKEN + id);
	}
}
